//*****************************************************************************
//    # #              Name   : reg_arbiter
//  #     #            Date   : Jul. 10, 2021
// #    #  #  #     #  Author : Qiwei Wu
//  #     #  # #  # #  Version: 1.0
//    # #  #    #   #
// reg_arbiter.sv
//
// Change History:
//  VER.   Author         DATE              Change Description
//  1.0    Qiwei Wu       Jul. 10, 2021     Initial Release
//*****************************************************************************

module reg_arbiter
#(
   parameter                   SLAVE_CNT = 5
)
(
   input                       clk,
   if_reg_ctrl.slave           reg_if_i,
   if_reg_ctrl.master          reg_if_o[0:SLAVE_CNT-1]
);

genvar i, j;
wire [SLAVE_CNT-1:0] slave_sel;
wire [31:0] slave_rdata [0:SLAVE_CNT-1];
wire [0:SLAVE_CNT-1] slave_rdata_swap[31:0];

generate
   for(i = 0; i < SLAVE_CNT; i = i + 1)
   begin: GEN
      assign slave_sel[i] = reg_if_i.addr[13:8] == i;
      
      assign reg_if_o[i].addr  = reg_if_i.addr[7:0];
      assign reg_if_o[i].wdata = reg_if_i.wdata;
      assign reg_if_o[i].we    = (slave_sel[i] == 1'b1)? reg_if_i.we : 4'h0;
      assign reg_if_o[i].en    = (slave_sel[i] == 1'b1)? reg_if_i.en : 1'b0;
      assign slave_rdata[i]    = reg_if_o[i].rdata & {32{slave_sel[i]}};
      
      for(j = 0; j < 32; j = j + 1)
      begin
         assign slave_rdata_swap[j][i] = slave_rdata[i][j];
      end
   end
   
   for(i = 0; i < 32; i = i + 1)
   begin
      assign reg_if_i.rdata[i] = |slave_rdata_swap[i];
   end
endgenerate

endmodule
